package thread;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: fzykd
 * Date: 2022-10-28
 * Time: 20:13
 */
class BlockQueue {
    private int[] elem = new int[1000];
    private int head;
    private int tail;
    private int size;


    //处理阻塞
    Object locker = new Object();
    //时刻牢记wait和notify是配合synchronized一起使用的

    //入队列
    public void put(int val) throws InterruptedException {
       synchronized (locker){
           if (elem.length == size){
               //当队列为满是阻塞等待 等待出队列了来通知
               locker.wait();
           }
           elem[tail] = val;
           tail++;
           //处理tail走到最后
           if (tail>= elem.length){
               tail = 0;
           }
           //最后有效数据个数++
           size++;
           locker.notify();
       }
    }

    //出队列
    public Integer take() throws InterruptedException {
       synchronized (locker){
           if (size == 0){
               //当为空的时候 阻塞等待 等待有进队列的元素来通知
               locker.wait();
           }
           int ret = elem[head];
           head++;
           if (head == elem.length){
               head = 0;
           }
           size--;
           locker.notify();
           return ret;
       }
    }
}

//实现线程安全的阻塞队列
public class Demo3 {
    private static BlockQueue queue = new BlockQueue();

    //基于阻塞队列 实现一个生产者消费者模型
    public static void main(String[] args) {
        //生产者
        Thread t1 = new Thread(() -> {
            int num = 0;
            while (true){
                System.out.println("生产了: " + num);
                try {
                    queue.put(num);
                    num++;
                    Thread.sleep(30);
                    //当生产着 生产的慢的时候 消费者就只能跟着生产者的步伐走了
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        Thread t2 = new Thread(() -> {
            while (true){
                int num = 0;
                try {
                    num = queue.take();
                    System.out.println("消费了: " + num);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });
        t1.start();
        t2.start();
    }



    public static void main1(String[] args) throws InterruptedException {
        BlockQueue queue = new BlockQueue();
        queue.put(1);
        queue.put(12);
        queue.put(38);
        queue.put(199);

        System.out.println(queue.take());
        System.out.println(queue.take());

    }
}
